# game.py

from roles import ROLES, get_card_value
from cards import Deck

class CardGameApp:
    def __init__(self, player_selections):
        self.deck = Deck()
        self.num_players = len(player_selections)
        self.players = {}
        for i, (player_name, role) in enumerate(player_selections.items()):
            self.players[player_name] = {
                'name': player_name, 'role': role, 'cards': [],
                'choices_left': 3, 'discarded_cards': [], 'selected_cards': [],
                'used_restart': False, 'score': 0, 'itsuki_skill_used_this_turn': False,
                'skill_log': []
            }
        self.player_order = list(self.players.keys())
        self.current_player_index = 0
        self.current_card_index = 0

    def start_game(self):
        for player_name in self.players:
            self.deck.shuffle()
            self.players[player_name]['cards'] = [self.deck.deal_card() for _ in range(6)]
        self.current_player_index = 0
        self.current_card_index = 0
        
    def get_current_player_data(self):
        if self.is_game_over(): return None
        return self.players[self.player_order[self.current_player_index]]

    def get_current_card(self):
        player_data = self.get_current_player_data()
        if player_data and self.current_card_index < len(player_data['cards']):
            return player_data['cards'][self.current_card_index]
        return None

    def is_turn_over(self):
        player_data = self.get_current_player_data()
        if not player_data: return True
        return player_data['choices_left'] <= 0 or self.current_card_index >= len(player_data['cards'])
    
    def is_game_over(self):
        return self.current_player_index >= self.num_players

    def make_choice(self, choice: bool):
        if self.is_turn_over(): return
        player_data = self.get_current_player_data()
        card = self.get_current_card()
        if not choice:
            is_face_card = card['rank'] in ['J', 'Q', 'K']
            if player_data['role'] == "皇伊月" and not player_data['itsuki_skill_used_this_turn'] and is_face_card:
                player_data['choices_left'] += 1
                player_data['itsuki_skill_used_this_turn'] = True
                new_card = self.deck.deal_card()
                if new_card: player_data['cards'].append(new_card)
        if choice:
            if player_data['choices_left'] > 0:
                player_data['selected_cards'].append(card)
                player_data['choices_left'] -= 1
        else:
            player_data['discarded_cards'].append(card)
        self.current_card_index += 1
        if self.is_turn_over():
            while self.current_card_index < len(player_data['cards']):
                player_data['discarded_cards'].append(player_data['cards'][self.current_card_index])
                self.current_card_index += 1
    
    def restart_turn(self):
        if self.is_game_over(): return
        player_data = self.get_current_player_data()
        if player_data['role'] == "桃喰绮罗莉" and not player_data['used_restart']:
            player_data['cards'] = [self.deck.deal_card() for _ in range(6)]
            player_data['selected_cards'] = []
            player_data['discarded_cards'] = []
            player_data['choices_left'] = 3
            player_data['itsuki_skill_used_this_turn'] = False
            self.current_card_index = 0
            player_data['used_restart'] = True

    def apply_turn_end_skills(self, player_data):
        if player_data['role'] == "桃喰莉莉香" and player_data['selected_cards']:
            min_card = min(player_data['selected_cards'], key=get_card_value)
            player_data['selected_cards'].remove(min_card)
            player_data['discarded_cards'].append(min_card)
            new_card = self.deck.deal_card()
            if new_card: player_data['selected_cards'].append(new_card)
            return {"swapped_out": min_card, "swapped_in": new_card}
        return None

    def calculate_turn_score(self, player_data):
        score = sum(get_card_value(card) for card in player_data['selected_cards'])
        player_data['skill_log'] = []
        if player_data['role'] in ROLES:
            skill_result = ROLES[player_data['role']]["skill"](player_data, self)
            if isinstance(skill_result, dict):
                score += skill_result.get("bonus", 0)
                if "log" in skill_result:
                    player_data['skill_log'] = skill_result.get("log", [])
            elif isinstance(skill_result, (int, float)):
                score += skill_result
        player_data['score'] = score
        return score

    def advance_to_next_player(self):
        if self.is_game_over(): return
        self.current_player_index += 1
        self.current_card_index = 0
        if not self.is_game_over():
            player_data = self.get_current_player_data()
            player_data['used_restart'] = False
            player_data['itsuki_skill_used_this_turn'] = False
    
    def get_post_game_skill_players(self):
        return [name for name, data in self.players.items() if ROLES[data['role']].get("skill_type") == "interactive_post_game"]
    
    def apply_post_game_skill(self, caster_name, targets):
        caster_data = self.players[caster_name]
        role_info = ROLES[caster_data['role']]
        effect = role_info.get("skill_effect", {})
        action = effect.get("action")

        if action == "modify_score" and len(targets) == 1:
            target_name = targets[0]
            score_mod = effect.get("score_modifier", 0)
            self.players[target_name]['score'] += score_mod
            return f"{caster_name} 对 {target_name} 发动了技能，使其分数 {score_mod:+}！"
            
        elif action == "swap_scores" and len(targets) == 2:
            target1_name, target2_name = targets[0], targets[1]
            score1 = self.players[target1_name]['score']
            score2 = self.players[target2_name]['score']
            self.players[target1_name]['score'] = score2
            self.players[target2_name]['score'] = score1
            return f"{caster_name} 发动技能，交换了 {target1_name} ({score1}分) 和 {target2_name} ({score2}分) 的分数！"
            
        return "技能发动失败：无效的目标或行动。"

    def finalize_results(self):
        sorted_players = sorted(self.players.items(), key=lambda x: x[1]['score'], reverse=True)
        penalty_player = None
        if self.num_players > 2:
            top_two_names = [p[0] for p in sorted_players[:2]]
            for name, data in self.players.items():
                if data['role'] == "下月売奥理" and name not in top_two_names:
                    penalty_player = name
        return sorted_players, penalty_player